package com.linsen.core.log.area;

import cn.hutool.core.util.ObjectUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;

import java.io.IOException;
import java.io.InputStream;

/**
 * IP 工具类
 *
 * IP 数据源来自 ip2region.xdb 精简版，基于 <a href="https://gitee.com/zhijiantianya/ip2region"/> 项目
 *
 * @author wanglhup
 */
@Slf4j
public class IPUtils {

    /**
     * 初始化 SEARCHER
     */
    @SuppressWarnings("InstantiationOfUtilityClass")
    private final static IPUtils INSTANCE = new IPUtils();

    /**
     * IP 查询器，启动加载到内存中
     */
    private static Searcher SEARCHER;

    /**
     * 私有化构造
     */
    private IPUtils() {
        try {
            long now = System.currentTimeMillis();

            InputStream inputStream = new ClassPathResource("/ip2region.xdb").getInputStream();
            byte[] bytes = FileCopyUtils.copyToByteArray(inputStream); //in_b为转换之后的结果
            SEARCHER = Searcher.newWithBuffer(bytes);
            log.info("启动加载 IPUtils 成功，耗时 ({}) 毫秒", System.currentTimeMillis() - now);
        } catch (IOException e) {
            log.error("启动加载 IPUtils 失败", e);
        }
    }

    /**
     * 查询 IP 对应的地区编号
     *
     * @param ip IP 地址，格式为 127.0.0.1
     * @return 地区id
     */
    @SneakyThrows
    public static IpArea getAreaId(String ip) {
        //每个 ip 数据段的 region 信息都固定了格式：国家|区域|省份|城市|ISP，只有中国的数据绝大部分精确到了城市，其他国家部分数据只能定位到国家，后前的选项全部是0。
        System.out.println("ip:"+ip);
        String search = SEARCHER.search(ip.trim());
        System.out.println(search);

        IpArea ipArea = new IpArea();
        if (ObjectUtil.isNotEmpty(search)){
            String[] ipArr = search.split("\\|");

            String country = ipArr[0];
            if (!ObjectUtil.equal("0",country)){
                ipArea.setCountry(country);
                Area area = AreaUtils.getArea(country);
                if (ObjectUtil.isNotNull(area)){
                    ipArea.setCountryCode(area.getId());
                }
            }

            String region = ipArr[1];
            if (!ObjectUtil.equal("0",region)){
                ipArea.setRegion(region);
                Area area = AreaUtils.getArea(region);
                if (ObjectUtil.isNotNull(area)){
                    ipArea.setRegionCode(area.getId());
                }
            }

            String province = ipArr[2];
            if (!ObjectUtil.equal("0",province)){
                ipArea.setProvince(province);
                Area area = AreaUtils.getArea(province);
                if (ObjectUtil.isNotNull(area)){
                    ipArea.setProvinceCode(area.getId());
                }
            }

            String city = ipArr[3];
            if (!ObjectUtil.equal("0",city)){
                ipArea.setCity(city);
                Area area = AreaUtils.getArea(city);
                if (ObjectUtil.isNotNull(area)){
                    ipArea.setCityCode(area.getId());
                }
            }

            String isp = ipArr[4];
            ipArea.setIsp(isp);
        }
        return ipArea;
    }
}
